//
// Created by Administrator on 2022/6/14.
//
#include "utiledef.h"
#include "DeviceFun.h"
#include "serialportapi.h"


int RMUHFRFID_Send_CMD_RFID(int handlers, uchar *payload, uint payload_size);
int RMUHFRFID_Resp_CMD_RFID(int handlers, uchar *inbuf,uint  *inlen, int timer_out);

#define UARTTIMEOUTS  10
//安卓接口层
int Device_UARTSendRecv(int porthandlers,uchar *sbuf,uint slen,uchar *rbuf,uint *rlen,int timeouts)
{
    RMUHFRFID_Send_CMD_RFID(porthandlers,sbuf,slen);
    return RMUHFRFID_Resp_CMD_RFID(porthandlers,rbuf,rlen,timeouts);
}

//串口透传数据
//接受数据
//A5 5A 00 58 头和长度
//10个字节帧格式 E0 0A 02 00 00 24 00 18 00 00
//从这时转发的数据，BB 47 FF 02 00 59 57 43 5A 35 43 48 5F 4D 30 5F 48 57 56 31 2E 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 59 57 43 5A 35 43 48 5F 4D 30 5F 53 57 56 32 2E 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1A 16 9A 0D 0A
int Device_UARTPORT_SendRecv(int porthandlers,uchar no,uchar *sbuf,uint slen,uchar *rbuf,uint *rlen,int timeouts)
{
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;
    uchar sport=0x00;

    int retvalue=-1;

    if(no==0x2)
    {
        sport=0x22;
    } else if(no==0x3){

        sport=0x23;
    }else if(no==0x4){

        sport=0x24;
    }else if(no==0x5){

        sport=0x25;
    }else if(no==0x6){

        sport=0x26;
    }else if(no==0x7){

        sport=0x27;
    }  else if(no==0x8){

        sport=0x28;
    } else{
        return -10;
    }

    //设备类型
    sendbuf[0x00]=0xe0;
    sendbuf[0x01]=0x0a;
    //设备标志
    sendbuf[0x02]=0x02;
    sendbuf[0x03]=0x0;
    sendbuf[0x04]=0x0;
    sendbuf[0x05]=sport;
    //序号
    sendbuf[0x06]=0x0;
    sendbuf[0x07]=0x01;
    //帧类型
    sendbuf[0x08]=0x00;
    sendbuf[0x09]=0x00;

    memcpy(&sendbuf[0x0a],sbuf,slen);
    sendlen=slen+0x0a;

    retvalue=Device_UARTSendRecv(porthandlers,sendbuf,sendlen,recvbuf,&reclen,timeouts);
    if(retvalue==0x00)
    {
        if(recvbuf[6]==sport)       //发送与接受通道号相同
        {
            return  -1000+retvalue;
        }
        memcpy(rbuf,&recvbuf[10],reclen-10);    //OK
        rlen[0]=reclen-10;
    }
    return retvalue;

}

//称重数据,NO 0~9
//输入：从地址开始输入数据
//输出：从地址开始输出数据
int Device_weighPORT_SendRecv(int porthandlers,uchar no,uchar *sbuf,uint slen,uchar *rbuf,uint *rlen,int timeouts) {
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen = 0;
    uint reclen = 0;
    uchar sendport = 0;
    uchar len;
    uchar cs;

    int retvalue = -1;

    rlen[0]=0x00;

    if ((no >=0)&&(no < 5)){
        sendport=2;
    }else if ((no >=5)&&(no <= 10)){
        sendport=3;
    }
    else{
        return -100;
    }

    len=0;
    cs=0;
    len=slen+4;
    sendbuf[0]=0xbb;        //HEAD
    sendbuf[1]=len;         //len
    //sendbuf[2]=0x00;        //ADDRESS
    //sendbuf[3]=0x61;         //cmd
    cs=cs^sendbuf[0];
    cs=cs^sendbuf[1];
    for(uchar i=0;i<slen;i++)
    {
        sendbuf[2+i]=sbuf[i];
        cs=cs^sbuf[i];
    }

    sendbuf[2+slen]=cs;
    sendbuf[3+slen]=0x16;

    sendlen=len;
    retvalue=Device_UARTPORT_SendRecv(porthandlers,sendport,sendbuf,sendlen,recvbuf,&reclen,timeouts);
    cs=0;
    if(recvbuf[0]!=0xbb)
    {
        return -101;
    }
    for(uchar i=0;i<(reclen-1);i++)
    {
        cs=cs^recvbuf[i];
    }
    if( cs!=0x00)
    {
        return -102;
    }
    memcpy(&rbuf[0],&recvbuf[2],reclen-2);
    rlen[0]=reclen-2;
    //返回带地址，命令，状态
    //recvbuf[2],地址
    //recvbuf[3],命令
    //recvbuf[4],状态
    //从recvbuf[5] 开始时数据
    return retvalue;
}


/**
   * @param Portstr
   * @return
   */
int Device_Port(uchar *Portstr){
    Set_SerialPort(Portstr);
    return 0x00;
}

/**
 * @return
 */
//串口初始化
int Device_Init(){
    return OpenComm(0,115200);

}

/**
 * @return
 */
int Device_Close(int porthandler){
    return CloseComm(porthandler);
}


/**开门
 * @param porthandler,串口句柄
 * @param no，通道号
 * @param times，开门时间，触发时间，0x0000,一直开
 * @return
 */
int Device_DoorOpen(int porthandler ,uchar no,int times){

    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;

    //设备类型
    sendbuf[0x00]=0xe0;
    sendbuf[0x01]=0x0a;

    //设备标志
    sendbuf[0x02]=0x0;
    sendbuf[0x03]=0x0;
    sendbuf[0x04]=0x0;
    sendbuf[0x05]=0x0;
    //序号
    sendbuf[0x06]=0x0;
    sendbuf[0x07]=0x0;
    //帧类型
    sendbuf[0x08]=0x42;
    sendbuf[0x09]=0x03;
    //数据项数量
    sendbuf[0x0A]=0x00;
    sendbuf[0x0B]=0x01;

    //数据类型
    sendbuf[0x0C]=0x42;
    sendbuf[0x0D]=0x02;
    sendbuf[0x0E]=0x04;

    sendbuf[0x0F]=no&0X07;
    sendbuf[0x10]=0x01;

    sendbuf[0x11]=(uchar)(times&0xff);
    sendbuf[0x12]=(uchar)((times>>8)&0xff);

    sendlen=0x13;

    retvalue=Device_UARTSendRecv(porthandler,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    return retvalue;
}

/**关闭
 * @param porthandler,串口句柄
 * @param no，通道号，
 * @return
 */
int Device_DoorClose(int porthandler,uchar no){
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;

    //设备类型
    sendbuf[0x00]=0xe0;
    sendbuf[0x01]=0x0a;

    //设备标志
    sendbuf[0x02]=0x0;
    sendbuf[0x03]=0x0;
    sendbuf[0x04]=0x0;
    sendbuf[0x05]=0x0;
    //序号
    sendbuf[0x06]=0x0;
    sendbuf[0x07]=0x0;
    //帧类型
    sendbuf[0x08]=0x42;
    sendbuf[0x09]=0x03;
    //数据项数量
    sendbuf[0x0A]=0x00;
    sendbuf[0x0B]=0x01;

    //数据类型
    sendbuf[0x0C]=0x42;
    sendbuf[0x0D]=0x02;
    sendbuf[0x0E]=0x04;

    sendbuf[0x0F]=no&0X07;
    sendbuf[0x10]=0x00;

    sendbuf[0x11]=0x00;
    sendbuf[0x12]=0x00;

    sendlen=0x13;

    retvalue=Device_UARTSendRecv(porthandler,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    return retvalue;
}

/**检测门状态
 * @param porthandler,串口句柄
 * @param no，通道号
 * @return
 */
int Device_DoorCheck(int porthandler,uchar no){
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;

    //设备类型
    sendbuf[0x00]=0xe0;
    sendbuf[0x01]=0x0a;

    //设备标志
    sendbuf[0x02]=0x0;
    sendbuf[0x03]=0x0;
    sendbuf[0x04]=0x0;
    sendbuf[0x05]=0x0;
    //序号
    sendbuf[0x06]=0x0;
    sendbuf[0x07]=0x0;
    //帧类型
    sendbuf[0x08]=0x42;
    sendbuf[0x09]=0x02;
    //数据项数量
    sendbuf[0x0A]=0x00;
    sendbuf[0x0B]=0x01;

    //数据类型
    sendbuf[0x0C]=0x42;
    sendbuf[0x0D]=0x01;
    sendbuf[0x0E]=0x02;

    sendbuf[0x0F]=no&0X07;
    sendbuf[0x10]=0x01;

    sendlen=0x10;

    retvalue=Device_UARTSendRecv(porthandler,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0) {

        return -2000;
    }
    //                                             10 11 12 13  14 15
    //A5 5A 00 17 E0 0A 00 00 00 00 00 00    62 02 00 42 01 02  01 01  DC 0D 0A
    //                                             ^  =0
    if(recvbuf[10]!=0x00)
    {
        return -2011;
    }
    if(recvbuf[14]!=no)
    {
        return -2012;
    }
    retvalue=recvbuf[15]&0XF;
    return retvalue;
}

//称重,检测两个模块
int Device_weigher_Getversion(int porthandler,uchar* buf)
{
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;

//    while(1)
//    {
//        retvalue=RMUHFRFID_Resp_CMD_RFID(porthandler,recvbuf,&reclen,10);
//#if COM_DEBUG
//        LOGD("RMUHFRFID_Resp_CMD_RFID data 1  :%d",retvalue);
//        logHexstring(reclen,recvbuf);
//#endif
//
//    }


    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x02; //COMMAND
    memset(buf,0x00,32);
    sendlen=2;
    retvalue=Device_weighPORT_SendRecv(porthandler,0,sendbuf,sendlen,recvbuf,&reclen,30);
    if(retvalue!=0){

        return -1000;
    }
    retvalue=Device_weighPORT_SendRecv(porthandler,5,sendbuf,sendlen,recvbuf,&reclen,30);
    if(retvalue!=0) {

        return -2000;

    }
    if(recvbuf[2]!=0x00) {
        return -3000;
    }
    memcpy(buf,&recvbuf[3],32);
    return retvalue;
}

/**设置参数
 * @param porthandler ,串口句柄
 * @param no          ，通道号
 * @param buf，返回数据
 * @return，=0 成功，其他值错误
 */
int Device_WeigherSetParam(int porthandler,uchar* buf){
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;
    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x62; //COMMAND

    memcpy(&sendbuf[2],buf,10);

    sendlen=12;

    retvalue=Device_weighPORT_SendRecv(porthandler,0,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1000;
    }
    if(recvbuf[2]!=0x00)
    {
        return -3000;
    }
    retvalue=Device_weighPORT_SendRecv(porthandler,5,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1100;
    }
    if(recvbuf[2]!=0x00)
    {
        return -3100;
    }
    return retvalue;
}


/**获取参数
 * @param porthandler,串口句柄
 * @param no，通道号
 * @param dbuf
 * @return =0 成功，其他值错误
 */
int Device_WeigherGetParam(int porthandler,uchar* dbuf){
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;
    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x63; //命令
    sendbuf[0x02]=1; //0x00
    sendbuf[0x03]=1; //0x00

    sendlen=4;

    retvalue=Device_weighPORT_SendRecv(porthandler,0,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1000;
    }
    if(recvbuf[2]!=0x00)
    {
        return -3000;
    }
    memcpy(dbuf,&recvbuf[3],10);

    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x63; //命令
    sendbuf[0x02]=1; //0x00
    sendbuf[0x03]=1; //0x00

    sendlen=4;

    retvalue=Device_weighPORT_SendRecv(porthandler,5,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1100;
    }
    if(recvbuf[2]!=0x00)
    {
        return -3100;
    }

    return retvalue;
}



/** 单通道校正，置零
 * @param porthandler
 * @param no
 * @return =0 成功，其他值错误
 */
int Device_WeigherAdjust(int porthandler,uchar no){
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;
    uchar ch;
    if(no>=5)
    {
        ch=no-5;
    }
    else
    {
        ch=no;
    }
    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x64; //COMMAND
    sendbuf[0x02]=1; //COMMAND
    sendbuf[0x03]=ch&0x07; //COMMAND
    sendlen=4;
    memset(recvbuf,0x00,100);
    retvalue=Device_weighPORT_SendRecv(porthandler,no,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1000;
    }
    if(recvbuf[2]!=0x00)
    {
        return -3000;
    }
    //BB 0D 00 61 00 01 01 00 00 01 4C 9A 16,整个包
    //00 61 00 01 01 00 00 01 4C , 函数输出
    //memcpy(buf,&recvbuf[5],4);
    return retvalue;
}


/**所有通道校正置零
 * @param porthandler
 * @return =0 成功，其他值错误
 */
int Device_WeigherAdjustALL(int porthandler){
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;
    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x64; //COMMAND
    sendbuf[0x02]=5; //COMMAND
    sendbuf[0x03]=0; //COMMAND
    sendlen=4;
    memset(recvbuf,0x00,100);
    retvalue=Device_weighPORT_SendRecv(porthandler,0,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1000;
    }
    if(recvbuf[2]!=0x00)
    {
        return -3000;
    }


    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x64; //COMMAND
    sendbuf[0x02]=5; //COMMAND
    sendbuf[0x03]=0; //COMMAND
    sendlen=4;
    memset(recvbuf,0x00,100);
    retvalue=Device_weighPORT_SendRecv(porthandler,5,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1100;
    }
    if(recvbuf[2]!=0x00)
    {
        return -3100;
    }
    //BB 0D 00 61 00 01 01 00 00 01 4C 9A 16,整个包
    //00 61 00 01 01 00 00 01 4C , 函数输出
    //memcpy(buf,&recvbuf[5],4);
    return retvalue;
}

/** 单通道校正，标定，需要带标定重量
 * @param porthandler
 * @param no
 *
 * @return =0 成功，其他值错误
 */
int Device_WeigherCablierate(int porthandler,uchar no,int value){
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;
    uchar ch;
    if(no>=5)
    {
        ch=no-5;
    }
    else
    {
        ch=no;
    }
    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x65; //COMMAND
    sendbuf[0x02]=1; //COMMAND
    sendbuf[0x03]=ch&0x07; //COMMAND
    sendbuf[0x04]=(uchar)(value>>24);      //H高字节在前
    sendbuf[0x05]=(uchar)(value>>16);
    sendbuf[0x06]=(uchar)(value>>8);
    sendbuf[0x07]=(uchar)(value);

    sendlen=8;

    retvalue=Device_weighPORT_SendRecv(porthandler,no,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1000;
    }
//    if(recvbuf[2]!=0x00)
//    {
//        return -3000;
//    }
    return retvalue;
}


/**所有通道标定
 * @param porthandler
 * @return =0 成功，其他值错误
 */
int Device_WeigherCablierateALL(int porthandler,int value){
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;
    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x65; //COMMAND
    sendbuf[0x02]=5; //项目数量
    sendbuf[0x03]=0; //开始序号
    sendbuf[0x04]=(uchar)(value>>24);      //H高字节在前
    sendbuf[0x05]=(uchar)(value>>16);
    sendbuf[0x06]=(uchar)(value>>8);
    sendbuf[0x07]=(uchar)(value);

    sendbuf[0x08]=(uchar)(value>>24);      //H高字节在前
    sendbuf[0x09]=(uchar)(value>>16);
    sendbuf[0x0a]=(uchar)(value>>8);
    sendbuf[0x0b]=(uchar)(value);

    sendbuf[0x0c]=(uchar)(value>>24);      //H高字节在前
    sendbuf[0x0d]=(uchar)(value>>16);
    sendbuf[0x0e]=(uchar)(value>>8);
    sendbuf[0x0f]=(uchar)(value);

    sendbuf[0x10]=(uchar)(value>>24);      //H高字节在前
    sendbuf[0x11]=(uchar)(value>>16);
    sendbuf[0x12]=(uchar)(value>>8);
    sendbuf[0x13]=(uchar)(value);

    sendbuf[0x14]=(uchar)(value>>24);      //H高字节在前
    sendbuf[0x15]=(uchar)(value>>16);
    sendbuf[0x16]=(uchar)(value>>8);
    sendbuf[0x17]=(uchar)(value);
    sendlen=0x18;

    retvalue=Device_weighPORT_SendRecv(porthandler,0,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1000;
    }
//    if(recvbuf[2]!=0x00)
//    {
//        return -3000;
//    }

    sendlen=0x18;

    retvalue=Device_weighPORT_SendRecv(porthandler,5,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1001;
    }
//    if(recvbuf[2]!=0x00)
//    {
//        return -3002;
//    }
    return retvalue;

}


/**获得单通道重量
 * @param porthandler,串口句柄
 * @param no，通道号，1~10
 * @param buf
 * @return =0 成功，其他值错误
 */
int Device_WeigherGet(int porthandler,uchar no,uchar* buf){

    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;

    uchar ch;
    if(no>=5)
    {
        ch=no-5;
    }
    else
    {
        ch=no;
    }

    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x61; //COMMAND
    sendbuf[0x02]=1; //COMMAND
    sendbuf[0x03]=ch&0x07; //COMMAND
    sendlen=4;

    retvalue=Device_weighPORT_SendRecv(porthandler,no,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);
    if(retvalue!=0x00)
    {
        return -1000;
    }
    if(recvbuf[2]!=0x00)
    {
        return -3000;
    }
    //BB 0D 00 61 00 01 01 00 00 01 4C 9A 16,整个包
    //00 61 00 01 01 00 00 01 4C , 函数输出
    memcpy(buf,&recvbuf[5],4);
    return retvalue;
}

/**，获取全部通道重量
 * @param porthandler,串口句柄
 * @param no，通道号 ，通道号
 * @param buf，
 * @return
 */
int Device_WeigherGetAll(int porthandler,uchar no,uchar* buf){
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;

    //第一个通道
    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x61; //COMMAND
    sendbuf[0x02]=5; //项目数
    sendbuf[0x03]=0x0; //起始编号
    sendlen=4;
    retvalue=Device_weighPORT_SendRecv(porthandler,0,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);

    if(retvalue!=0x00)
    {
        return -1000;
    }
    if(recvbuf[2]!=0x00)
    {
        return -3000;
    }
    memcpy(buf,&recvbuf[5],20);
    //第二个通道
    sendbuf[0x00]=0x00; //ADDRESS
    sendbuf[0x01]=0x61; //COMMAND
    sendbuf[0x02]=5; //COMMAND
    sendbuf[0x03]=0x0; //COMMAND
    sendlen=4;
    retvalue=Device_weighPORT_SendRecv(porthandler,5,sendbuf,sendlen,recvbuf,&reclen,UARTTIMEOUTS);

    if(retvalue!=0x00)
    {
        return -1000;
    }
    if(recvbuf[2]!=0x00)
    {
        return -3000;
    }
    memcpy(&buf[20],&recvbuf[5],20);
    return retvalue;

}


//串口透传数据
/**
 * @param porthandler,串口句柄
 * @param no，通道号
 * @param slen
 * @param sendbuf
 * @param rlen
 * @param recbuf
 * @param timeout
 * @return =0 成功，其他值错误
 */

int Device_UartSendRecv(int porthandler,uchar no,int slen,uchar* sbuf,int *rlen,uchar* rbuf,int timeout){
    uchar sendbuf[1024];
    uchar recvbuf[1024];
    uint sendlen=0;
    uint reclen=0;

    int retvalue=-1;
    retvalue=Device_UARTPORT_SendRecv(porthandler,no,sendbuf,sendlen,rbuf,rlen,timeout);

    return retvalue;
}